package com.zh.chat.controller;

import java.io.FileNotFoundException;
import java.net.ServerSocket;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.zh.chat.entity.Friend;
import com.zh.chat.entity.UDPProtocol;
import com.zh.chat.entity.User;
import com.zh.chat.entity.UserStatus;
import com.zh.chat.file.FileManager;
import com.zh.chat.file.FileOperationUtil;
import com.zh.chat.file.FileType;
import com.zh.chat.net.FileClient;
import com.zh.chat.net.FileServer;
import com.zh.chat.service.impl.OnlineUserManager;

class AnalyzeThread implements Runnable {
	private com.zh.chat.entity.UDPProtocol protocol = null;
	ServerController controller = null;

	public AnalyzeThread(UDPProtocol protocol, ServerController controller) {
		this.protocol = protocol;
		this.controller = controller;
	}

	public void run() {
		analyzeSwitcher();// 分析客户端发送过来的请求
	}

	/**
	 * 根据传入的参数字符串做出不同的反应
	 * 
	 * @param command
	 */
	private void analyzeSwitcher() {

		/**
		 * protocol的格式请参看命令表
		 */
		com.zh.chat.entity.User user = OnlineUserManager.getUser(protocol
				.getRequestId());
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if (user != null || protocol.getCode() == UDPProtocol.REQ_LOGIN
				|| protocol.getCode() == UDPProtocol.REQ_IP || protocol.getCode() == UDPProtocol.REQ_REGIST) {// 确定用户是在线用户的情况下执行switch
			switch (protocol.getCode()) {
			case UDPProtocol.RESP_KEEP_ONLINE:
				keepOnline(user);
				break;// 保持在线
			case UDPProtocol.REQ_USERINFO:
				sendUserInfo(user);
				break;// 发送用户资料给客户端
			case UDPProtocol.REQ_SEND_MSG:
				sendMsgToUser();
				break;// 发送消息给某用户
			case UDPProtocol.REQ_FRIENDS_LIST:
				sendFriends(user);
				break;// 获取好友
			case UDPProtocol.REQ_FRIEND_MATERIAL:
				sendFriendById(user);
				break;// 获取某个好友资料
			case UDPProtocol.REQ_SEND_FILE:
				sendFile();
				break;// 请求服务器发送文件
			case UDPProtocol.REQ_RECIVE_FILE:
				reciveFile();
				break;// 请求服务器接收文件
			case UDPProtocol.REQ_RECIVE_VOICE:
				initVoice();
				break;// 请求服务器与好友建立连接
			case UDPProtocol.REQ_MODIFY_PASSWORD:
				modifyPwd();
				break;// 修改某ID密码
			case UDPProtocol.REQ_MODIFY_MATERIAL:
				modifyUser();
				break;// 修改某ID的用户资料
			case UDPProtocol.REQ_MODIFY_PROFILE:
				modifyHead();
				break;// 修改头像图片
			case UDPProtocol.REQ_MODIFY_FRIEND_DIVIDED:
				modifyFriDivide(user);
				break;// 修改某个好友的分组
			case UDPProtocol.REQ_ADD_FRIEND:
				addFriend(user);
				break;// 增加好友到某个分组
			case UDPProtocol.REQ_DEL_FRIEND:
				delFriend(user);
				break;// 删除好友
			case UDPProtocol.REQ_LOGIN:
				login();
				break;// 登入
			case UDPProtocol.REQ_LOGOUT:
				logout();
				break;// 登出
			case UDPProtocol.REQ_IP:
				requestIP();
				break;// 登出
			case UDPProtocol.REQ_CHANGE_STATUS:
				changeStatus();
				break;// 改变用户状态
			case UDPProtocol.REQ_REGIST:
				register();
				break;// 注册
			default:
				break;//
			}
		}
	}

	/**
	 * 保持在线的方法
	 * 
	 * @param id
	 */
	private void keepOnline(User user) {
		if (user.getStatus() == UserStatus.CHECKING) {
			User client = (User) protocol.getData();
			user.setStatus(client.getStatus());
			OnlineUserManager.setStatus(user.getSysId(), client.getStatus());
		} else {
			System.out.println("用户" + user.getSysId() + "已经掉线");
		}
	}

	/**
	 * 发送用户资料给用户
	 */
	private void sendUserInfo(User user) {
		protocol.setCode(UDPProtocol.RESP_USERINFO);
		protocol.setData(user);
		protocol.setClazz(user.getClass().getName());
		controller.getNetService().send(protocol);
	}

	/**
	 * 向targetId的用户发送消息 1判断用户是否在线 在线：给双方发送UDPProtocol 不在线：给请求方发送targetId=0L的包
	 * 
	 * @param targetId
	 * @param requestId
	 * @param text
	 */
	private void sendMsgToUser() {
		java.lang.Long tarId = protocol.getTargetId();
		User user = OnlineUserManager.getUser(tarId);
		if (user != null) {
			UDPProtocol tarProtocol = new UDPProtocol();
			tarProtocol.setRequestId(tarId);
			tarProtocol.setTargetId(protocol.getRequestId());
			tarProtocol.setCode(UDPProtocol.RESP_SEND_MSG);
			tarProtocol.setClientIp(user.getClientIp());
			tarProtocol.setClientPort(user.getClientPort());
			tarProtocol.setData(protocol.getData());
			tarProtocol.setClazz("".getClass().getName());
			controller.getNetService().send(tarProtocol);
			protocol.setCode(UDPProtocol.RESP_SEND_MSG);
			protocol.setRequestId(protocol.getTargetId());
			protocol.setTargetId(0L);
			// 规定，如果服务器返回的UDP包中请求ID和目标ID是一样的说明发送成功，服务器返回发送给其他用户的消息
			controller.getNetService().send(protocol);
		} else {
			protocol.setCode(UDPProtocol.RESP_SEND_MSG);
			protocol.setTargetId(-1L);
			String msg = "该用户不在线";
			protocol.setData(msg);
			protocol.setClazz(msg.getClass().getName());
			controller.getNetService().send(protocol);
		}
	}

	/**
	 * 根据用户ID获取该用户的好友
	 * <p>
	 * 格式: (friend_id:nickname:divide_name)*n
	 * 
	 * @param id
	 */
	private void sendFriends(User user) {
		String path = FileOperationUtil.getFilePath(FileType.DATA,
				user.getSysId(), "friendList.data");
		ServerSocket server = controller.getNetService().getTcpDTO()
				.getFreeSocket();
		Integer port = server.getLocalPort();
		protocol.setCode(UDPProtocol.RESP_FRIENDS_LIST);
		protocol.setClazz(port.getClass().getName());
		protocol.setData(port);
		try {
			new FileServer(server, path, controller, protocol);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void initSculpture(List<Friend> list) {
		for (Friend friend : list) {
			String oldPath = FileOperationUtil.getFilePath(FileType.SCULPTURE,
					friend.getFriendId(), friend.getImage());
			String newPath = FileOperationUtil.getFilePath(FileType.SCULPTURE,
					friend.getSysId(), friend.getImage());
			try {
				FileManager.copyFile(oldPath, newPath);
			} catch (FileNotFoundException e) {
				oldPath = FileOperationUtil.getFilePath(FileType.IMAGE, null,
						"noImage.jpg");
				try {
					FileManager.copyFile(oldPath, newPath);
				} catch (FileNotFoundException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	/**
	 * 将targetId的用户资料发送给requestId的用户
	 * 
	 * @param targetId
	 * @param requestId
	 */
	private void sendFriendById(User user) {
	}

	private void sendFile() {
		Object o = protocol.getData();
		if (o instanceof String) {
			String info = (String) o;
			String[] infos = StringUtils.split(info, ':');
			if(infos.length!=1){
			String path = FileOperationUtil.getFilePath(
					Integer.parseInt(infos[0]), protocol.getRequestId(),
					infos[1]);
			ServerSocket server = controller.getNetService().getTcpDTO()
					.getFreeSocket();
			Integer port = server.getLocalPort();
			protocol.setData(port + ":" + infos[0]);
			protocol.setClazz(port.getClass().getName());
			protocol.setCode(UDPProtocol.RESP_SERVER_SEND_FILE_ACK);
				try {
					new FileServer(server, path, controller ,protocol);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 接受客户端请求
	 */
	private void reciveFile() {
		Object o = protocol.getData();
		if (o instanceof String) {
			String info = (String) o;
			String[] infos = StringUtils.split(info, ':');// 0:文件类型，1：发送文件的端口号
			String path = FileOperationUtil.getFilePath(
					Integer.parseInt(infos[0]), protocol.getRequestId(), null);
			Integer port = Integer.parseInt(infos[1]);
			try {
				new FileClient(path, protocol.getClientIp(), port);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 建立好友语音连接
	 */
	private void initVoice() {
		java.lang.Long tarId = protocol.getTargetId();
		User user = OnlineUserManager.getUser(tarId);
		if (user != null) {
			UDPProtocol tarProtocol = new UDPProtocol();
			tarProtocol.setTargetId(protocol.getRequestId());
			tarProtocol.setRequestId(tarId);
			tarProtocol.setCode(UDPProtocol.RESP_RECIVE_VOICE);
			tarProtocol.setClientIp(user.getClientIp());
			tarProtocol.setClientPort(user.getClientPort());
			tarProtocol.setData(protocol.getData());
			tarProtocol.setClazz("".getClass().getName());
			controller.getNetService().send(tarProtocol);
			protocol.setCode(UDPProtocol.RESP_RECIVE_VOICE);
			protocol.setData("ok");
			protocol.setRequestId(protocol.getRequestId());
			protocol.setTargetId(user.getSysId());
			// 规定，如果服务器返回的UDP包中请求ID和目标ID是一样的说明发送成功，服务器返回发送给其他用户的消息
			controller.getNetService().send(protocol);
		} else {
			protocol.setCode(UDPProtocol.RESP_RECIVE_VOICE);
			protocol.setTargetId(-1L);
			String msg = "false";
			protocol.setData(msg);
			protocol.setClazz(msg.getClass().getName());
			controller.getNetService().send(protocol);
		}
	}
	/**
	 * 修改用户密码
	 * 
	 * @param id
	 * @param oldpwd
	 * @param newpwd
	 */
	private void modifyPwd() {
	}

	/**
	 * 根据usreInfo修改id用户的用户资料
	 * 
	 * @param id
	 * @param userInfo
	 */
	private void modifyUser() {
		java.lang.Long id = protocol.getRequestId();
		Object object = protocol.getData();
		if (object instanceof User) {
			User user = (User) object;
			User dbuser = controller.getUserService().findById(id);
			String pwd = dbuser.getUserPwd();
			if (pwd.equals(user.getUserPwd())) {
				dbuser.setBirthday(user.getBirthday());
				dbuser.setName(user.getName());
				dbuser.setNickname(user.getNickname());
				dbuser.setClientIp(protocol.getClientIp());
				dbuser.setClientPort(protocol.getClientPort());
				dbuser.setSex(user.getSex());
				dbuser.setStatus(user.getStatus());
				user = lazy2Bean(dbuser, user);
				user = controller.getUserService().updateUser(dbuser);
				OnlineUserManager.addUser(user);
				// 发送修改成功信号
				protocol.setCode(UDPProtocol.RESP_MODIFY_MATERIAL);
				protocol.setData(user);
				controller.getNetService().send(protocol);
				List<Friend> list = controller.getFriendsService().getFriends(protocol.getRequestId());
				for (Friend friend : list) {
					// 更新好友的json好友信息文件
					List<Friend> subList = controller.getFriendsService().getFriends(friend.getFriendId());
					controller.getFriendsService().makeFriendsFile(friend.getFriendId(), FileType.DATA, subList);
				}
			} else {
				// 发送修改失败信号
				protocol.setCode(UDPProtocol.RESP_MODIFY_MATERIAL);
				protocol.setClazz(new Boolean(false).getClass().getName());
				protocol.setData(new Boolean(false));
				controller.getNetService().send(protocol);
			}
		}
	}

	/**
	 * 更新用户头像
	 */
	private void modifyHead() {
		java.lang.Long id = protocol.getRequestId();
		Object object = protocol.getData();
		if (object instanceof String) {
			String info = (String) object;
			String[] infos = StringUtils.split(info, ':');// 0:文件类型，1：发送文件的端口号
			String path = FileOperationUtil.getFilePath(
					Integer.parseInt(infos[0]), protocol.getRequestId(), null);
			Integer port = Integer.parseInt(infos[1]);
			try {
				new FileClient(path, protocol.getClientIp(), port);
			} catch (Exception e) {
				return;
			}

			User dbuser = controller.getUserService().findById(id);
			String oldImage = dbuser.getImage();
			String pwd = dbuser.getUserPwd();
			dbuser.setImage(infos[2]);
			User user = controller.getUserService().updateUser(dbuser);
			if (user != null) {
				String oldPath = FileOperationUtil.getFilePath(FileType.SCULPTURE, user.getSysId(), oldImage);
				FileManager.delFile(oldPath);
				OnlineUserManager.addUser(user);
				// 发送修改成功信号
				protocol.setCode(UDPProtocol.RESP_MODIFY_PROFILE);
				protocol.setData(user);
				controller.getNetService().send(protocol);
				List<Friend> list = controller.getFriendsService().getFriends(protocol.getRequestId());
				for (Friend friend : list) {
					List<Friend> friendslist = controller.getFriendsService()//更新好友的好友列表文件
							.getFriends(friend.getFriendId());
					controller.getFriendsService().makeFriendsFile(friend.getFriendId(), FileType.DATA, list);// 访问数据库并生成json格式的好友信息文件
					initSculpture(list);
				}
			}
		}
	}

	/**
	 * 修改某个好友的分组
	 * 
	 * @param targetId
	 * @param requestId
	 * @param divide_name
	 */
	private void modifyFriDivide(User user) {
	}

	/**
	 * 添加好友到默认分组
	 * 
	 * @param id
	 * @param friend_id
	 * @param divide_name
	 */
	private void addFriend(User user) {
	}

	/**
	 * 删除好友
	 * 
	 * @param targetId
	 * @param requestId
	 */
	private void delFriend(User user) {
	}

	/**
	 * 用户登录方法
	 * 
	 * @param id
	 * @param pwd
	 */
	private void login() {
		Object object = protocol.getData();
		User user = null;
		if (object instanceof User) {
			user = (User) object;
			User temp = OnlineUserManager.getUser(user.getSysId());
			if (temp == null) {
				User dbuser = controller.getUserService().login(
						user.getSysId(), user.getUserPwd());
				if (dbuser != null) {
					dbuser.setStatus(user.getStatus());
					dbuser.setClientIp(protocol.getClientIp());
					dbuser.setClientPort(protocol.getClientPort());
					dbuser.setClientFilePort(protocol.getClientFilePort());
					dbuser.setLastLoginDate(new java.util.Date());
					dbuser.setStatus(user.getStatus());// 设置用户在线状态
					dbuser = controller.getUserService().updateUser(dbuser);
					OnlineUserManager.addUser(dbuser);
					// dbuser转化为静态的user
					user = lazy2Bean(dbuser, user);// 将hibernate的bean对象转化为User对象

					List<Friend> list = controller.getFriendsService()
							.getFriends(user.getSysId());
					controller.getFriendsService().makeFriendsFile(user.getSysId(), FileType.DATA, list);// 访问数据库并生成json格式的好友信息文件
					initSculpture(list);
					protocol.setCode(UDPProtocol.RESP_LOGIN);
					protocol.setClazz(Boolean.class.getName());
					protocol.setData(new Boolean(true));
					controller.getNetService().send(protocol);
				} else {
					protocol.setCode(UDPProtocol.RESP_LOGIN);
					protocol.setClazz(Boolean.class.getName());
					protocol.setData(new Boolean(false));
					controller.getNetService().send(protocol);
				}
			} else {
				protocol.setCode(UDPProtocol.RESP_LOGIN);
				protocol.setClazz(Boolean.class.getName());
				protocol.setData(new Boolean(false));
				controller.getNetService().send(protocol);
			}
		} else {
			System.out.println(this.getClass().getName() + "244行报错");
		}
	}

	private User lazy2Bean(User dbuser, User user) {
		user.setBirthday(dbuser.getBirthday());
		user.setLastLoginDate(dbuser.getLastLoginDate());
		user.setName(dbuser.getName());
		user.setNickname(dbuser.getNickname());
		user.setRegisterDate(dbuser.getRegisterDate());
		user.setSex(dbuser.getSex());
		user.setUserPwd(dbuser.getUserPwd());
		user.setImage(dbuser.getImage());
		return user;
	}

	/**
	 * 登出方法
	 * 
	 * @param id
	 */
	private void logout() {
		OnlineUserManager.removeUser(protocol.getRequestId());
		controller.getUserService().logout(protocol.getRequestId());
		protocol.setCode(UDPProtocol.RESP_LOGOUT);
		protocol.setData(new Boolean(true));
		protocol.setClazz(new Boolean(true).getClass().getName());
		controller.getNetService().send(protocol);
	}

	private void requestIP() {
		protocol.setData("欢迎使用");
		protocol.setClazz("".getClass().getName());
		protocol.setCode(UDPProtocol.RESP_IP);
		controller.getNetService().send(protocol);
	}

	private void changeStatus() {
		Object o = protocol.getData();
		if (o instanceof Integer) {
			Integer status = (Integer) o;
			OnlineUserManager.changeStatus(protocol.getRequestId(), status);
			User user = OnlineUserManager.getUser(protocol.getRequestId());
			controller.getUserService().updateUser(user);
			protocol.setClazz(user.getClass().getName());
			protocol.setData(user);
			protocol.setCode(UDPProtocol.RESP_CHANGE_STATUS);
			if (status == 5) {
				logout();
			}
			controller.getNetService().send(protocol);
		}
	}

	private void register() {
		Object o = protocol.getData();
		if(o instanceof User){
			User tempUser = (User)o;
			tempUser = controller.getUserService().register(tempUser);
			protocol.setCode(UDPProtocol.RESP_REGIST);
			protocol.setData(tempUser);
			protocol.setClazz(com.zh.chat.entity.User.class.getName());
			controller.getNetService().send(protocol);
		}
	}
}// 解析命令的Thread 进程类